<template>
  <div class="watch-container">
    <div>
      <hr>
      <p>count的值: {{ count }}</p>
      <button @click="add">+1</button>
    </div>
    <hr>
    <div>
      <hr>
      <p> name: {{ obj.name }}</p>
      <p> age: {{ obj.age }}</p>
      <p> age: {{ obj.brand.name }}</p>
      <button @click="updateName">改名字</button>
      <button @click="updateBrandName">改品牌名字</button>
      <button @click="updateAge">年龄+1</button>
    </div>
  </div>
</template>

<script>
import {computed, reactive, ref, watch} from "vue";

export default {
  name: "Watch",
  setup() {
    const count = ref(0);

    const add = () => {
      count.value++

    }
    // 当你需要监听数据的变化就可以使用watch
    // 1.监听一个ref数据
    // 1.1 第一个参数 需要监听的目标
    // 1.2 第二个参数 改变后触发的函数
    watch(count, (newVal, oldVal) => {
      // ref-newVal: 1, ref-oldVal: 0
      console.log(`ref-newVal: ${newVal}, ref-oldVal: ${oldVal}`)
    })


    const obj = reactive({
      name: 'ls',
      age: 10,
      brand: {
        id: 1,
        name: '宝马'
      }
    });

    const updateName = () => {
      obj.name = 'llhuang10'
    }

    const updateAge = () => {
      obj.age++
    }

    const updateBrandName = () => {
      obj.brand.name = '五菱宏光'
    }

    // 可以通过计算属性 + 序列化 + 反序列化生成新的对象, 来避免此问题
    const newObj = computed(() => {
      return JSON.parse(JSON.stringify(obj));
    })

    // 2.监听一个reactive数据 | 能监听到一个对象深层次的属性
    watch(newObj, (newVal, oldVal) => {
      console.log('newObj数据改变了')
      console.log(newVal, oldVal)
    })


    // 2.监听一个reactive数据 | 能监听到一个对象深层次的属性
    watch(obj, (newVal, oldVal) => {
      // obj-newVal: llhuang10, obj-oldVal: llhuang10
      // console.log(`obj-newVal: ${newVal.name}, obj-oldVal: ${oldVal.name}`)
      // console.log(newVal.name, oldVal.name)
      console.log('数据改变了')
      console.log(newVal, oldVal)
      // console.log(newVal.age, oldVal.age)
    })


    // 3.监听多个数据的改变 | 能监听到一个对象深层次的属性
    watch([count, obj], () => {
      console.log('多个数据发生改变了')
    })

    // 4.此时监听对象中指定某一个属性的变化 例如: obj.age
    // 需要写成函数返回该属性的方式才能监听到
    watch(() => obj.age, () => {
      console.log('监听obj.age改变')
    })

    // 5.监听对象中深层次的对象中指定某一个属性的变化  例如: obj.brand.name
    watch(() => obj.brand.name, () => {
      console.log('----- 监听obj.brand.name属性变化 -----')
    })

    // 6.监听对象中深层次的对象中属性的变化  例如: obj.brand.name | obj.brand.age
    // 这是就需要使用 深度监听了 { deep: true }
    watch(() => obj.brand, () => {
      console.log('----- 监听obj.brand的某一个属性变化 -----')
    }, {deep: true})

    return {
      count,
      add,
      obj,
      updateName,
      updateAge,
      updateBrandName
    }
  }
}
</script>

<style scoped>

</style>
